package com.hskn.hss.module.maintaincfg.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hskn.hss.core.annotation.DataScope;
import com.hskn.hss.core.domain.BaseEntity;
import com.hskn.hss.core.utils.LoginUtils;
import com.hskn.hss.entity.AjaxResult;
import com.hskn.hss.exception.ExcelReaderDataException;
import com.hskn.hss.exception.HssException;
import com.hskn.hss.module.costdict.service.ICostDictService;
import com.hskn.hss.module.costdictitem.entity.CostDictItem;
import com.hskn.hss.module.costdictitem.mapper.CostDictItemMapper;
import com.hskn.hss.module.depart.entity.SysDepart;
import com.hskn.hss.module.depart.mapper.SysDepartMapper;
import com.hskn.hss.module.depart.service.ISysDepartService;
import com.hskn.hss.module.maintaincfg.entity.TlMaintainCfg;
import com.hskn.hss.module.maintaincfg.mapper.TlMaintainCfgMapper;
import com.hskn.hss.module.maintaincfg.service.ITlMaintainCfgService;
import com.hskn.hss.module.maintaincfg.to.TlMaintainCfgListTO;
import com.hskn.hss.module.tlcar.entity.TlCar;
import com.hskn.hss.module.tlcar.mapper.TlCarMapper;
import com.hskn.hss.module.tlcar.service.ITlCarService;
import com.hskn.hss.module.tlcartype.entity.TlCarType;
import com.hskn.hss.module.tlcartype.service.ITlCarTypeService;
import com.hskn.hss.module.tlcostdateil.entity.TlCostDateil;
import com.hskn.hss.module.tlcostdateil.service.ITlCostDateilService;
import com.hskn.hss.module.user.entity.User;
import com.hskn.hss.module.user.mapper.UserMapper;
import com.hskn.hss.module.user.service.IUserService;
import com.hskn.hss.module.userdepart.entity.SysUserDepart;
import com.hskn.hss.module.userdepart.mapper.SysUserDepartMapper;
import com.hskn.hss.to.ForIdsTO;
import com.hskn.hss.utils.AttributeUtils;
import com.hskn.hss.utils.GroupingByUtils;
import com.hskn.hss.utils.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author hskn
 * @since 2021-05-06
 */
@Service
public class TlMaintainCfgServiceImpl extends ServiceImpl<TlMaintainCfgMapper, TlMaintainCfg> implements ITlMaintainCfgService {

    @Resource
    TlMaintainCfgMapper TlMaintainCfgMapper;
    @Resource
    SysUserDepartMapper sysUserDepartMapper;
    @Resource
    ITlCostDateilService tlCostDateilService;
    @Resource
    ITlCarService carService;
    @Resource
    ITlCarTypeService carTypeService;
    @Resource
    ISysDepartService departService;
    @Resource
    IUserService userService;
    @Resource
    UserMapper userMapper;
    @Resource
    ICostDictService costDictService;
    @Resource
    CostDictItemMapper costDictItemMapper;
    @Resource
    private SysDepartMapper departMapper;
    @Resource
    private TlCarMapper carMapper;

    @Override
    @Transactional(rollbackFor = {RuntimeException.class, Error.class}) //添加事务
    public AjaxResult insert(JSONObject params) {

        String uid = LoginUtils.getUser().getUid();
        TlMaintainCfg tlMaintainCfg = params.getObject("data", TlMaintainCfg.class);

        QueryWrapper<SysUserDepart> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SysUserDepart::getUserid, uid);
        String deptid = sysUserDepartMapper.selectOne(queryWrapper).getDepid();

        tlMaintainCfg.setCreatby(uid);
        tlMaintainCfg.setCreattime(new Date());
        tlMaintainCfg.setId(StringUtils.uuid());
        tlMaintainCfg.setDeptid(deptid);
        TlCar car = null;
        if (tlMaintainCfg != null) {
            car = carService.getById(tlMaintainCfg.getCarnumid());
            tlMaintainCfg.setCartype(car.getCartypeid());
            tlMaintainCfg.setDeptidforcar(car.getCardeptid());
        }
        int i = TlMaintainCfgMapper.insert(tlMaintainCfg);

        //添加对应的 明细
        for (TlCostDateil tlCostDateil : tlMaintainCfg.getDateils()) {
            tlCostDateil.setId(StringUtils.uuid());
            tlCostDateil.setMaintbid(tlMaintainCfg.getId());

            JSONObject dateilParam = new JSONObject().fluentPut("data", tlCostDateil);
            try {
                tlCostDateilService.insert(dateilParam);
            } catch (Exception e) {
                e.printStackTrace();
                log.error("报错ERROR", e);
                return AjaxResult.fail("明细表添加失败，请稍后再试");
            }
        }
        boolean flag = i > 0;

        if (flag) {
            return AjaxResult.success("操作成功");
        } else {
            return AjaxResult.fail("操作失败，请稍后再试");
        }
    }

    @Override
    @Transactional(rollbackFor = {RuntimeException.class, Error.class}) //添加事务
    public AjaxResult update(JSONObject params) throws HssException {

        String uid = LoginUtils.getUser().getUid();
        TlMaintainCfg tlMaintainCfg = params.getObject("data", TlMaintainCfg.class);

        tlMaintainCfg.setUpdateby(uid);
        tlMaintainCfg.setUpdatetime(new Date());
        TlCar car = null;
        if (tlMaintainCfg != null) {
            car = carService.getById(tlMaintainCfg.getCarnumid());
            tlMaintainCfg.setCartype(car.getCartypeid());
            tlMaintainCfg.setDeptidforcar(car.getCardeptid());
        }
        int i = TlMaintainCfgMapper.updateById(tlMaintainCfg);
        //添加对应的 操作权限
        tlCostDateilService.deleteByMap(tlMaintainCfg.getId());
        //添加对应的 明细
        for (TlCostDateil tlCostDateil : tlMaintainCfg.getDateils()) {
            tlCostDateil.setId(StringUtils.uuid());
            tlCostDateil.setMaintbid(tlMaintainCfg.getId());

            JSONObject dateilParam = new JSONObject().fluentPut("data", tlCostDateil);
            try {
                tlCostDateilService.insert(dateilParam);
            } catch (Exception e) {
                e.printStackTrace();
                log.error("报错ERROR", e);
                return AjaxResult.fail("明细表添加失败，请稍后再试");
            }
        }

        boolean flag = i > 0;
        if (flag) {
            return AjaxResult.success("操作成功");
        } else {
            return AjaxResult.fail("操作失败，请稍后再试");
        }
    }

    @Override
    @Transactional(rollbackFor = {RuntimeException.class, Error.class})
    public AjaxResult deleteByid(ForIdsTO forIdsTO) throws HssException {
        int i = TlMaintainCfgMapper.deleteBatchIds(forIdsTO.getIds());
        boolean flag = i > 0;
        if (flag) {
            return AjaxResult.success("操作成功");
        } else {
            return AjaxResult.fail("操作失败，请稍后再试");
        }
    }

    @Override
    public TlMaintainCfg getDetailById(JSONObject params) throws HssException {
        String id = params.getString("id");
        TlMaintainCfg tlMaintainCfg = TlMaintainCfgMapper.selectById(id);
        List<TlCostDateil> tlCostDateilList = tlCostDateilService.getitemListByParentId(id);
        if (!tlCostDateilList.isEmpty()) {
            tlMaintainCfg.setDateils(tlCostDateilList);
        }
        TlCar car = null;
        TlCarType carType = null;
        SysDepart depart = null;
        User user = null;
        CostDictItem costDictItem = null;
        if (tlMaintainCfg != null) {
            car = carService.getById(tlMaintainCfg.getCarnumid());
            depart = departService.getById(tlMaintainCfg.getDeptid());
            costDictItem = costDictItemMapper.selectById(tlMaintainCfg.getRepairreason());
        }
        if (costDictItem != null) {
            tlMaintainCfg.setRepairreasonName(costDictItem.getCostname());
        }
        if (car != null) {
            carType = carTypeService.getById(car.getCartypeid());
            user = userService.getById(car.getDriverid());
            tlMaintainCfg.setCarCardNum(car.getCarnumber());
        }
        if (carType != null) {
            tlMaintainCfg.setCarTyeName(carType.getTypename());
        }
        if (depart != null) {
            tlMaintainCfg.setDeptName(depart.getDepartName());
        }
        if (user != null) {
            tlMaintainCfg.setDriverName(user.getName());
        }
        return tlMaintainCfg;
    }

    @Override
    @DataScope(deptAlias = "deptidforcar", userAlias = "creatBy")
    public JSONObject getList(BaseEntity baseEntity, JSONObject params) throws HssException {
        Long page = StringUtils.isEmpty(params.getLong("page")) ? 1 : params.getLong("page");
        Long size = StringUtils.isEmpty(params.getLong("size")) ? 10 : params.getLong("size");
        JSONObject json = new JSONObject();

        Map map = new HashMap();
        map.put("carNumid", params.getString("carNumid"));
        map.put("serviceVendorName", params.getString("serviceVendorName"));
        map.put("deptIdForCar", params.getString("deptIdForCar"));
        map.put("orderNo", params.getString("orderNo"));
        map.put("startTime", AttributeUtils.timeCompletion(params.getString("startTime"), 's'));
        map.put("endTime", AttributeUtils.timeCompletion(params.getString("endTime"), 'e'));
        map.put("param", baseEntity.getParams());
        Page<TlMaintainCfg> maintainPage = new Page<>(page, size, true);
        IPage<TlMaintainCfg> iPage = TlMaintainCfgMapper.listmaintain(maintainPage, map);
        List<TlMaintainCfg> list = iPage.getRecords();
        Map<String, User> userMap = userService.getUserMap();
        Map<String, TlCar> carMap = carService.getCarMap(new QueryWrapper<>());
        Map<String, SysDepart> departMap = departService.getDepartMap(new QueryWrapper<>());
        Map<String, TlCarType> carTypeMap = carTypeService.getCarTypeMap(new QueryWrapper<>());
        Map<String, CostDictItem> costDictItemMap = costDictService.getitemForCostDictItemMap(new QueryWrapper<>());
        for (TlMaintainCfg tlMaintainCfg : list) {
            if (carMap != null && carMap.containsKey(tlMaintainCfg.getCarnumid())) {
                tlMaintainCfg.setCarCardNum(carMap.get(tlMaintainCfg.getCarnumid()).getCarnumber());
            }
            if (userMap != null && userMap.containsKey(tlMaintainCfg.getDriverid())) {
                tlMaintainCfg.setDriverName(userMap.get(tlMaintainCfg.getDriverid()).getName());
            }
            if (carTypeMap != null && carTypeMap.containsKey(tlMaintainCfg.getCartype())) {
                tlMaintainCfg.setCarTyeName(carTypeMap.get(tlMaintainCfg.getCartype()).getTypename());
            }
            if (departMap != null && departMap.containsKey(tlMaintainCfg.getDeptid())) {
                tlMaintainCfg.setDeptName(departMap.get(tlMaintainCfg.getDeptid()).getDepartName());
            }
            if (costDictItemMap != null && costDictItemMap.containsKey(tlMaintainCfg.getRepairreason())) {
                tlMaintainCfg.setRepairreasonName(costDictItemMap.get(tlMaintainCfg.getRepairreason()).getCostname());
            }
        }

        json.put("total", iPage.getTotal());
        json.put("size", iPage.getSize());
        json.put("pages", iPage.getPages());
        json.put("current", iPage.getCurrent());
        json.put("maintainlist", iPage.getRecords());
        return json;
    }

    @Override
    public void excelReader(List<TlMaintainCfg> maintainCfgList) throws ExcelReaderDataException {

        String uid = LoginUtils.getUser().getUid();
        List<SysDepart> departList = departMapper.selectList(new QueryWrapper<>());
        List<CostDictItem> costDictItemList = costDictItemMapper.selectList(new QueryWrapper<>());
        List<TlCar> carList = carMapper.selectList(new QueryWrapper<>());
        Map<String, TlCar> carMap = new HashMap<>();
        if (!carList.isEmpty()) {
            carMap = carList.stream().collect(Collectors.groupingBy(TlCar::getCarnumber, Collectors.collectingAndThen(Collectors.toList(), value -> value.get(0))));
        }
        Map<String, SysDepart> departMap = new HashMap<>();
        if (!departList.isEmpty()) {
            Predicate<SysDepart> departNameNotNull = depart -> StringUtils.isNotEmpty(depart.getDepartName());
            departList = departList.stream().filter(departNameNotNull).collect(Collectors.toList());
            departMap = GroupingByUtils.getGroupingForMapEntity(departList, SysDepart::getDepartName, Collectors.collectingAndThen(Collectors.toList(), value -> value.get(0)));
        }
        Map<String, CostDictItem> costDictItemMap = new HashMap<>();
        if (!costDictItemList.isEmpty()) {
            Predicate<CostDictItem> nameNotNull = costDictItem -> StringUtils.isNotEmpty(costDictItem.getCostname());
            costDictItemList = costDictItemList.stream().filter(nameNotNull).collect(Collectors.toList());
            costDictItemMap = GroupingByUtils.getGroupingForMapEntity(costDictItemList, CostDictItem::getCostname, Collectors.collectingAndThen(Collectors.toList(), value -> value.get(0)));
        }
        Map<String, User> userMap = new HashMap<>();
        List<User> userList = userMapper.selectList(new QueryWrapper<>());
        userMap = GroupingByUtils.getGroupingForMapEntity(userList, User::getName, Collectors.collectingAndThen(Collectors.toList(), value -> value.get(0)));
        int num = 1;
        String str = "";
        for (TlMaintainCfg maintainCfg : maintainCfgList) {
            maintainCfg.setCreattime(new Date());
            maintainCfg.setCreatby(uid);
            if (StringUtils.isNotEmpty(maintainCfg.getCarCardNum())) {
                if (carMap.containsKey(maintainCfg.getCarCardNum())) {
                    maintainCfg.setCarnumid(carMap.get(maintainCfg.getCarCardNum()).getId());
                } else {
                    str += "第" + num + "条的" + "“‘" + "车牌号’:‘" + maintainCfg.getCarCardNum() + "’”" + "不存在;##";
                }
            } else {
                str += "第" + num + "条的“车牌号”不能为空;##";
            }
            if (departMap.containsKey(maintainCfg.getDeptName())) {
                maintainCfg.setDeptid(departMap.get(maintainCfg.getDeptName()).getId());
                maintainCfg.setDeptidforcar(departMap.get(maintainCfg.getDeptName()).getId());
            } else {
                str += "第" + num + "条的" + "“‘" + "所属机构’:‘" + maintainCfg.getDeptName() + "’”" + "不存在;##";
            }
            if (Objects.isNull(maintainCfg.getCosttime())) {
                str += "第" + num + "条的’保养日期‘时间格式不正确;##";
            }
            if (Objects.isNull(maintainCfg.getTotalcost())) {
                str += "第" + num + "条的“总费用”不能为空;##";
            }
            if (costDictItemMap.containsKey(maintainCfg.getRepairreasonName())) {
                maintainCfg.setRepairreason(costDictItemMap.get(maintainCfg.getRepairreasonName()).getId());
            } else {
                str += "第" + num + "条的" + "“‘" + "保养部位’:‘" + maintainCfg.getRepairreasonName() + "’”" + "不存在;##";
            }
            if (!userMap.containsKey(maintainCfg.getPayusername())) {
                str += "第" + num + "条的" + "“‘" + "缴费人’:‘" + maintainCfg.getPayusername() + "’”" + "不存在;##";
            }
            num++;
        }
        if (StringUtils.isNotEmpty(str)) {
            throw new ExcelReaderDataException("您导入的数据:##" + str);
        }
    }

    @Override
    @DataScope(deptAlias = "deptidforcar", userAlias = "creatBy")
    public List<TlMaintainCfg> getMaintainCfgList(TlMaintainCfgListTO inspectionCfgListTo, SimpleDateFormat format) throws ParseException {
        QueryWrapper<TlMaintainCfg> inspectionCfgQueryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotEmpty(inspectionCfgListTo.getDeptid())) {
            inspectionCfgQueryWrapper.lambda().eq(TlMaintainCfg::getDeptid, inspectionCfgListTo.getDeptid());
        }
        if (inspectionCfgListTo.getParams().containsKey("dataScope") && StringUtils.isNotEmpty(inspectionCfgListTo.getParams().get("dataScope").toString())) {
            inspectionCfgQueryWrapper.lambda().apply(inspectionCfgListTo.getParams().get("dataScope").toString());
        }
        if (StringUtils.isNotEmpty(inspectionCfgListTo.getCarNumid())) {
            inspectionCfgQueryWrapper.lambda().eq(TlMaintainCfg::getCarnumid, inspectionCfgListTo.getCarNumid());
        }
        if (StringUtils.isNotEmpty(inspectionCfgListTo.getMaintainOddNumbers())) {
            inspectionCfgQueryWrapper.lambda().eq(TlMaintainCfg::getOrderno, inspectionCfgListTo.getMaintainOddNumbers());
        }
        if (inspectionCfgListTo.getIds() != null && !inspectionCfgListTo.getIds().isEmpty()) {
            inspectionCfgQueryWrapper.lambda().in(TlMaintainCfg::getId, inspectionCfgListTo.getIds());
        }
        if (StringUtils.isNotEmpty(inspectionCfgListTo.getStartTime()) && StringUtils.isNotEmpty(inspectionCfgListTo.getEndTime())) {
            inspectionCfgQueryWrapper.lambda().ge(TlMaintainCfg::getCosttime, format.parse(inspectionCfgListTo.getStartTime()));
            inspectionCfgQueryWrapper.lambda().le(TlMaintainCfg::getCosttime, format.parse(inspectionCfgListTo.getEndTime()));
        }
        List<TlMaintainCfg> inspectionCfgList = TlMaintainCfgMapper.selectList(inspectionCfgQueryWrapper);
        return inspectionCfgList;
    }
}
